home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / C de cerca / Ejemplos / Capítulo 4 / CdeCerca.c < prev   
C/C++ Source or Header  |  1996-01-24  |  20KB  |  573 lines

  1. /*****************************************************************/
  2. /*
  3.         C de Cerca 4
  4.         Recursos: WIND y ALRT
  5.         Rafael Escoté - Enric Herrera
  6.         BlauSoft S.L. para MacFormat España - 1996
  7.                     
  8.         La descripción del código y la información sobre cómo preparar
  9.         el entorno de programación y generar estos programas, está contenida
  10.         en el ejemplar de MacFormat que los acompaña.
  11.  
  12. */
  13. /*****************************************************************/
  14.  
  15.  
  16.  
  17. /*
  18. LA TOOLBOX Y LOS FICHEROS 'UNIVERSAL HEADERS'
  19. ==============================================
  20. La Toolbox es una colección de funciones escritas por Apple
  21. que han sido ya compiladas y colocadas en los chips de ROM de cada
  22. Mac. 
  23. Para poder emplear en nuestros programas una de dichas funciones,
  24. debemos informar al compilador acerca de los posibles parámetros
  25. y valores de salida requeridos.
  26. En otras palabras, el compilador necesita el prototipo de la función
  27. existente en la Toolbox de forma que pueda verificar que el uso que de
  28. ella hagamos en nuestro programa sea correcto.
  29. Los ficheros APPLE UNIVERSAL HEADERS proporcionados por Apple no
  30. son más que ficheros de texto conteniendo los prototipos de cada una de
  31. las funciones de la Toolbox.
  32.  
  33. NOTA: Sólo para los más curiosos: En la carpeta que contiene el compilador,
  34. veréis una carpeta llamada 'MacOS Support' y en su interior una carpeta
  35. llamada 'Headers' y dentro de ella una carpeta llamada
  36. 'Universal Headers', que contiene todos los ficheros creados por Apple.
  37. */
  38.  
  39.  
  40.  
  41. /* 
  42. COMO DIFERENCIAR FUNCIONES PROPIAS Y DE LA TOOLBOX
  43. ===================================================
  44. A las funciones creadas por nosotros para este programa (y que por lo
  45. tanto no pertenecen a la Toolbox) les hemos dado nombres que comienzan
  46. por las iniciales MF. Por ejemplo, MF_PlaySnd(), MF_RandomColor() etc...
  47. Todas las restantes funciones que aparecen empleadas en el código, SON
  48. FUNCIONES PERTENECIENTES A LA TOOLBOX DE APPLE.
  49. (Una excepción: La función main() la hemos creado nosotros pero su nombre
  50. no puede ser otro que main(), por convención)
  51.  
  52.  
  53.  
  54. /****************************************************************    */
  55. /* PROTOTIPOS    DE LAS FUNCIONES QUE HEMOS CREADO                                         */
  56. /* PARA NUESTRO PROGRAMA                                                                                    */ 
  57. /****************************************************************    */
  58. void        main(void);                /* Esta función NO puede tener otro nombre */
  59. void        MF_InitToolbox         (void);
  60. void         MF_SetupMenus            (void);
  61. void         MF_AbreMiVentana    (void);
  62. void         MF_EscribeTexto        (void);
  63. void         MF_bucle_principal(void);
  64. void         MF_MenuBar                (long algoSeleccionado);
  65. void         MF_Update                    (WindowPtr ventana_a_refrescar);
  66.  
  67.  
  68.  
  69. /****************************************************************    */
  70. /* CONSTANTES Y VARIABLES GLOBALES                                                                 */
  71. /* DE USO GENERAL                                                                                                    */ 
  72. /****************************************************************    */
  73. Boolean gAcabarProg = false; /* Una variable global. 
  74.                                                                 Como siempre, las variables globales
  75.                                                                 las prefijamos con la letra 'g'.
  76.                                                                 Cuando gAcabarProg sea = true,
  77.                                                                 acabaremos el programa */
  78.  
  79.  
  80.  
  81. /****************************************************************    */
  82. /* CONSTANTES DEFINIENDO EL NUMERO DE RECURSO    (resource)                    */
  83. /* CORRESPONDIENTE A LA VENTANA DE ALERTA QUE ABRIREMOS                        */
  84. /* CUANDO EL USUARIO SELECCIONE 'Acerca de C de Cerca...'                    */
  85. /* DEL MENU Apple 
  86. /****************************************************************    */
  87. #define kAlertRsrcID    128    /* Nº del recurso ALRT */
  88.  
  89.  
  90.  
  91. /****************************************************************    */
  92. /* CONSTANTES Y VARIABLES GLOBALES                                                                 */
  93. /* RELACIONADAS CON LOS MENUS EN NUESTRO PROGRAMA                                    */ 
  94. /****************************************************************    */
  95. #define            kAppleMenuID        128    /* Nuevo recurso MENU para el menú Apple */
  96. #define            kArchivoMenuID    129    
  97. #define            kAcercaDe_Item    1
  98. #define            kSalirItem            1
  99.  
  100. MenuRef            gAppleMenu;
  101. MenuRef            gArchivoMenu;
  102.  
  103.  
  104.  
  105. /****************************************************************    */
  106. /* CONSTANTES Y VARIABLES GLOBALES                                                                 */
  107. /* RELACIONADAS CON LA VENTANA QUE ABRIREMOS                                            */ 
  108. /****************************************************************    */
  109. /* A diferencia de las versiones anteriores, en esta, la ventana que
  110.     abriremos la hemos creado previamente empleando ResEdit y formará
  111.     parte de los recursos de la aplicación */
  112.     
  113. /*
  114. Una constante con el numero de recurso de la ventana que hemos creado 
  115. empleando ResEdit
  116. */
  117. #define         kMiVentanaRsrcID    128    /* Nº del recurso WIND */
  118.  
  119. WindowPtr        gMiVentana = nil; /*  Variable de tipo 'pointer'.
  120.                                                                 Puntero a una estructura
  121.                                                                 de tipo WindowRecord  definida por Apple
  122.                                                                 en el fichero UNIVERSAL HEADER Windows.h
  123.                                                                 y que corresponderá 
  124.                                                                 a la ventana que crearemos 
  125.                                                                 NOTA sólo para curiosos: De hecho,
  126.                                                                 una variable WindowPtr apunta a la 
  127.                                                                 estructura GrafPort que forma parte de
  128.                                                                 la estructura WindowRecord. */
  129.  
  130.                                                                 
  131.                                                                 
  132. /*--------------------------------------------------------------------*/
  133. /* A PARTIR DE ESTE PUNTO, APARECE EL CODIGO DE LAS FUNCIONES CREADAS
  134.     ESPECIFICAMENTE PARA ESTE PROGRAMA. */
  135. /*--------------------------------------------------------------------*/
  136.  
  137.  
  138.  
  139. /****************************************************************    */
  140. /* main()                                                                 */
  141. /****************************************************************    */
  142. /*
  143.     Todos los programas en C poseen una función que debe llamarse main.
  144.     (NO PERTENECE A LA TOOLBOX)
  145.     Cuando un programa se pone en marcha, lo hace SIEMPRE ejecutando
  146.     en primer lugar la función main().
  147.     Es el punto de entrada a nuestra aplicación.
  148.     
  149.     Recibe:     nada
  150.     Que hace: Crea menús y pone una ventana en pantalla etc...
  151.     Salida:      void (nada)
  152. */
  153. void    main (void)
  154. {    
  155.     /* Antes de hacer nada, debemos inicializar la Toolbox del Mac                 */
  156.     /* Como sea que el procedimiento a seguir para inicializar la Toolbox */
  157.     /* es casi siempre el mismo, hemos creado una función MF_InitToolbox()*/
  158.     /* que contiene las llamadas estándar de inicialización */
  159.  
  160.     MF_InitToolbox();
  161.  
  162.     /* Ahora debemos preparar y mostrar la barra de menú, que contendrá */
  163.     /* los menús propios de nuestra aplicación */
  164.     
  165.     MF_SetupMenus();
  166.     
  167.     /* Ahora empleamos una función se encargará de abrir una ventana */
  168.     MF_AbreMiVentana();
  169.     
  170.     /* Una vez abierta la ventana, podemos escribir algo de texto en ella */
  171.     MF_EscribeTexto();
  172.     
  173.     /* Y ya podemos entrar en el bucle principal, que se encargará de
  174.          recoger e interpretar las acciones del usuario */    
  175.     MF_bucle_principal();
  176.     
  177.     /* Cuando el bucle principal haya terminado, será porque el usuario
  178.          desea acabar el programa.
  179.          Debemos liberar la memoria ocupada por nuestra ventana. */
  180.     DisposeWindow(gMiVentana);
  181.     
  182.     /* Y ya está, al acabarse la función main(), el Sistema cerrará
  183.          nuestra aplicación de forma automática */
  184.     
  185. } /* Fin de main() y del programa */
  186.  
  187.  
  188.  
  189. /****************************************************************    */
  190. /* MF_bucle_principal                                                     */
  191. /****************************************************************    */
  192. /*
  193.     Recibe:     nada
  194.     Que hace: Entra en un bucle y espera que se produzca una acción (evento)
  195.                         Según cual sea este, reacciona llamando una de las funciones que
  196.                         hemos creado en esta demo.
  197.     Salida:      nada
  198. */
  199. void MF_bucle_principal(void)
  200. {
  201.     /* Declaramos una variable del tipo EventRecord que llamaremos el_Evento */
  202.     EventRecord    el_Evento;     
  203.                                 /* 
  204.                                 Un EventRecord es una estructura declarada
  205.                                 por Apple en el fichero UNIVERSAL HEADER
  206.                                 Events.h y formada por las siguientes
  207.                                 variables:
  208.                                                          
  209.                             struct EventRecord {
  210.                                     EventKind                what;         (qué evento)
  211.                                     UInt32                    message;    (datos del evento)
  212.                                     UInt32                    when;            (cuando se produce)
  213.                                     Point                        where;        (coordenadas del evento)
  214.                                     EventModifiers    modifiers;(estado de las teclas
  215.                                                                                             especiales: CMD, Opt, etc...) 
  216.                                     };
  217.                                 */
  218.     
  219.     WindowPtr    la_ventana;    /* Guardaremos un puntero que nos indicará en que
  220.                                                      ventana (si es el caso) se ha producido un evento */
  221.     
  222.     
  223.     short    zona_de_la_ventana; /* También guardaremos el código que indica
  224.                                                              la zona de la ventana en que se produce un evento
  225.                                                              si es del tipo mouseDown
  226.                                                         */
  227.                                                         
  228.     
  229.     Boolean    hay_evento;    /* valor de salida de la función WaitNextEvent */
  230.                                             /* Lo ignoraremos en esta demo */
  231.     
  232.     while (gAcabarProg == false)
  233.     /* Mientras la variable global gAcabarProg sea falsa, repetiremos este bucle */
  234.     /* Cuando es usuario seleccione 'Salir' del menú Archivo, cambiaremos el */
  235.     /* valor de gAcabarProg a true (cierto) */
  236.     {
  237.         
  238.         hay_evento = WaitNextEvent(everyEvent, &el_Evento, 0L, 0L);
  239.         /* WaitNextEvent es una función de la ToolBox que nos proporciona
  240.              información acerca de las posibles acciones del usuario o eventos del
  241.              Sistema. Para ello, 'llena' de información las variables de la estructura
  242.              EventRecord (el_Evento, en nuestro caso) */ 
  243.         
  244.         switch(el_Evento.what)
  245.         {
  246.             case nullEvent:
  247.                     /* Ignoramos eventos nulos (ningún evento).*/
  248.             break;
  249.                     
  250.             case keyDown:
  251.             /* Se ha pulsado una tecla. Comprobaremos si también se ha pulsado
  252.                  la tecla de CMD y si es así, llamaremos la función que responde
  253.                  a la selección de opciones de menú */
  254.                 if(el_Evento.modifiers & cmdKey) /* Tecla de CMD pulsada? */
  255.                 {
  256.                MF_MenuBar(MenuKey( el_Evento.message & charCodeMask) ) ;
  257.            }
  258.             break;
  259.                     
  260.             case autoKey:
  261.                 /* Ignoramos los eventos de repetición, generados al mantener
  262.                      pulsada una tecla */
  263.             break;
  264.                     
  265.             case mouseDown:
  266.             /* clic del ratón en algún sitio...*/
  267.                 zona_de_la_ventana = FindWindow(el_Evento.where,&la_ventana);
  268.                 switch (zona_de_la_ventana)
  269.                 {
  270.                     case inDrag:/* clic en la barra de título. Para que el usuario     */
  271.                                             /* pueda arrastrar la ventana, simplemente hemos de    */
  272.                                             /* usar la función DragWindow() que se encarga del    */
  273.                                             /* proceso, hasta que se suelte el botón del ratón     */
  274.                         DragWindow(la_ventana,el_Evento.where,&qd.screenBits.bounds);
  275.                     break;
  276.                             
  277.                     case inMenuBar: /* clic en la barra de menús */
  278.                         MF_MenuBar(MenuSelect(el_Evento.where));
  279.                     break;
  280.                             
  281.                     default:
  282.                         /* Ignoramos clics en otras zonas de la ventana */
  283.                     break;
  284.                 }
  285.             break;
  286.                     
  287.             case mouseUp:
  288.             /* ignoraremos los eventos producidos al soltar el botón del ratón */
  289.             break;
  290.                 
  291.             case diskEvt:
  292.             /* También ignoraremos los eventos producidos al insertar un disco */
  293.             break;
  294.                 
  295.             case updateEvt:
  296.                 /*    Una ventana debe ser refrescada. Llamamos la función
  297.                         MF_Update, pasándole un puntero a la ventana en cuestión.
  298.                         La variable message de la estructura EventRecord, contiene
  299.                         dicho puntero, pero es necesario forzar (cast) su tipo al
  300.                         de WindowPtr */
  301.                 la_ventana = (WindowPtr)el_Evento.message;
  302.                 MF_Update( la_ventana );
  303.             break;
  304.                 
  305.             default:
  306.             /* En cualquier otro caso, ignoramos el evento */
  307.             break;
  308.                 
  309.         } /* Fin de switch(el_Evento.what) */
  310.             
  311.     } /* Fin de while (gAcabarProg == false) */
  312.         
  313.         
  314. } /* Fin de la función MF_bucle_principal() */
  315.  
  316.  
  317.  
  318. /****************************************************************    */
  319. /* MF_Update                                                                       */
  320. /****************************************************************    */
  321. /*
  322.     Esta función se emplea cuando MF_bucle_principal ha detectado un evento
  323.     del tipo updateEvt. El sistema lo genera cuando una ventana activa
  324.     es desplazada o cuando una ventana que no era la activa es activada.
  325.     En estos casos, la zona de la ventana que permanecía
  326.     oculta por otras ventanas debe ser refrescada, re-dibujando su contenido.
  327.     El sistema controla todas las ventanas abiertas y genera un evento updateEvt
  328.     cuando alguna zona de una ventana necesita ser refrescada.
  329.     
  330.     Recibe:     un puntero a la ventana que debe ser refrescada.
  331.     Que hace: Esta demo aprovecha la función MF_EscribeTexto(). Cuando la ventana
  332.                         necesita refrescarse, simplemente llamamos de nuevo MF_EscribeTexto()
  333.                         y la ventana se actualizará.
  334.                         
  335.     Salida:      void (nada)
  336. */
  337. void MF_Update( WindowPtr ventana_a_refrescar)
  338. {
  339.  
  340.     GrafPtr  old_port;                            /* Declaración de una variable de tipo
  341.                                                                          puntero (pointer) a un área gráfica */
  342.     
  343.     GetPort( &old_port );                        /* Preservamos el área gráfica actual */
  344.     
  345.     SetPort( ventana_a_refrescar );    /* Cambiamos de área, seleccionando la
  346.                                                                         correspondiente a la ventana que debe
  347.                                                                         refrescarse */
  348.   
  349.   BeginUpdate( ventana_a_refrescar );
  350.    
  351.     /* Aqui deberíamos llamar las funciones adecuadas para re-dibujar los
  352.          contenidos de nuestra ventana.  En este caso re-escribimos un texto
  353.          en la ventana
  354.     */
  355.          
  356.      MF_EscribeTexto();
  357.              
  358.     EndUpdate( ventana_a_refrescar );
  359.  
  360.     SetPort( old_port );                    /* recuperamos el área gráfica inicial */
  361.     
  362. } /* Fin de MF_Update() */
  363.  
  364.  
  365.  
  366. /****************************************************************    */
  367. /* MF_MenuBar                                                                       */
  368. /****************************************************************    */
  369. /*
  370.     Esta función reacciona cuando MF_bucle_principal ha detectado que el clic
  371.     del ratón se ha producido en la barra de menús de nuestro programa.
  372.     
  373.     Requiere: Un recurso de tipo ALRT en el fichero CdeCerca_4.µ.rsrc
  374.     Recibe:     una variable con la información del menu e item seleccionados
  375.     Que hace: Actúa en función de la posible selección de un item de alguno
  376.                         de nuestros menús.
  377.     Salida:      void (nada)
  378. */
  379. void MF_MenuBar(long algoSeleccionado)
  380. {
  381.     short    Que_Menu;
  382.     short    Que_Opcion;
  383.     short dummy;
  384.     Str255 ItemName;
  385.     GrafPtr oldPort;
  386.     
  387.     if(algoSeleccionado != 0L)
  388.     {
  389.         /* algoSeleccionado es un valor de tipo long (4 bytes)
  390.              que contiene en los 2 bytes superiores el número de menú seleccionado
  391.              y en los dos bytes inferiores, el número de la opción seleccionada
  392.              de dicho menú.
  393.              Para extraer ambos valores, emplearemos una funciones de la Toolbox,
  394.              HiWord y LoWord que nos devolverán los valores que nos interesan */
  395.              
  396.         Que_Menu = HiWord(algoSeleccionado);     /* 2 bytes superiores */
  397.         Que_Opcion = LoWord(algoSeleccionado);/* 2 bytes inferiores */
  398.         
  399.         switch(Que_Menu)
  400.         {
  401.             case kAppleMenuID:                                     /* Menú Apple (nuevo)                                    */
  402.                 if(Que_Opcion == kAcercaDe_Item)     /* Si es la opción 'Acerca de'     */
  403.                 {
  404.                     /* Empleamos la función Alert() de la Toolbox, para que el Sistema
  405.                          abra un cuadro de diálogo que hemos creado previamente usando
  406.                          ResEdit, como recurso de tipo ALRT.
  407.                          La función Alert() pasa el control de nuestro programa al Sistema
  408.                          y no nos lo devuelve hasta que el usuario haya cerrado la ventana de
  409.                          alerta
  410.                     */ 
  411.                     Alert(kAlertRsrcID,nil); /* Todo parado... */
  412.                 }
  413.                 else
  414.                 /* NO es la opción 'Acerca de'. Ha de ser algo del menú Apple */
  415.                 /* Puede ser cualquier cosa... carpetas, aplicaciones, documentos...*/
  416.                 {
  417.                     /* 1º Obtenemos el nombre del item seleccionado */
  418.                     GetItem(gAppleMenu,Que_Opcion, ItemName);
  419.                     
  420.                     GetPort(&oldPort);
  421.                     
  422.                     /* 2º Lo abrimos empleando la función OpenDeskacc() que */
  423.                     /* funcionará sea cual sea el tipo de objeto del menú Apple */
  424.                     /* seleccionado por el usuario. Podemos ignorar el valor que  */
  425.                     /* OpenDeskAcc() devuelve */
  426.                     dummy = OpenDeskAcc(ItemName);
  427.                     
  428.                     SetPort(oldPort);
  429.                 }    
  430.             break;
  431.             
  432.             case kArchivoMenuID:                                /* Menú Archivo                                         */
  433.                 switch(Que_Opcion)
  434.                 {
  435.                     case kSalirItem:                                /* Opción 'Salir'                                     */
  436.                         gAcabarProg = true;                        /*IMPORTANTE: Cambiamos el valor de
  437.                                                                                         la variable global que nos indica
  438.                                                                                         que debemos finalizar el programa */
  439.                     break;                                                
  440.                         
  441.                 } /* Fin de switch(Que_Opcion) */
  442.                 
  443.             break;
  444.         } /* Fin de switch(Que_Menu) */
  445.         
  446.         HiliteMenu(0);
  447.         
  448.     } /* Fin de if(algoSeleccionado != 0L) */
  449.     
  450. } /* Fin de función MF_MenuBar() */
  451.  
  452.  
  453.  
  454. /****************************************************************    */
  455. /* MF_InitToolbox                                                                                                 */
  456. /****************************************************************    */
  457. /*
  458.     Inicializa la Toolbox Macintosh. El orden de llamada a las diversas
  459.     rutinas es significativo! No lo cambie.
  460.  
  461.     Requiere: nada
  462.     Recibe:     nada
  463.     Cambia:      nada en la aplicación
  464.     Salida:      nada
  465. */
  466. void MF_InitToolbox (void)
  467. {
  468.     InitGraf(&qd.thePort);
  469.     InitFonts();
  470.     FlushEvents(everyEvent,0);
  471.     InitWindows();
  472.     InitMenus();
  473.     TEInit();
  474.     InitDialogs(0L);
  475.     InitCursor();
  476.                                 
  477. } /* Fin de MF_InitToolbox() */
  478.  
  479.  
  480.  
  481. /****************************************************************    */
  482. /* MF_SetupMenus                                                                                                    */
  483. /****************************************************************    */
  484. /*
  485. Inicializa y muestra los menús del programa.
  486.  
  487.     Requiere: Recursos de tipo MENU en el fichero CdeCerca_4.µ.rsrc
  488.                         Concretamente los recursos MENU nº 128 y 129
  489.     Recibe:     nada
  490.     Cambia:      asigna valor a las globales e instala el menú en la barra de menús
  491.     Salida:   nada
  492. */
  493. void MF_SetupMenus(void)
  494. {
  495.     
  496.     /* Primero, leer los recursos de menu */
  497.     gAppleMenu = GetMenu( kAppleMenuID );            
  498.     gArchivoMenu = GetMenu( kArchivoMenuID );
  499.     
  500.     /* Nuevo: Añadir, al menú Apple todo los que ya contiene... */
  501.     /* La función AppendResMenu() añade a un menú, los nombres de todos */
  502.     /* los recursos del tipo especificado como parámetro. En este caso 'DRVR' */
  503.     /* Qye resultan ser los items del menú Apple, ya sean programas, documentos */
  504.     /* etc... */
  505.     AppendResMenu( gAppleMenu, 'DRVR' );
  506.     
  507.     InsertMenu(gAppleMenu, 0);
  508.     InsertMenu(gArchivoMenu, 0);
  509.     
  510.     DrawMenuBar();
  511.     
  512. } /* Fin de MF_SetupMenus() */
  513.  
  514.  
  515.     
  516. /****************************************************************    */
  517. /* MF_AbreMiVentana                                                       */
  518. /****************************************************************    */
  519. /*
  520.     Abre la ventana (la única) de nuestro programa. A diferencia de las anteriores
  521.     versiones, en esta la ventana ha sido creada previamente empleando ResEdit
  522.     y guardada en el fichero de recursos CdeCerca_4.µ.rsrc.
  523.     Durante la compilación, los recursos de dicho fichero son copiados e
  524.     integrados en la aplicación resultante, quedando así en disposición de ser
  525.     empleados por la aplicación.
  526.     
  527.     Requiere: Recurso WIND 128 (En CdeCerca_4.µ.rsrc)
  528.     Recibe:     nada
  529.     Que hace: Crea una ventana...
  530.     Salida:      void (nada)
  531. */
  532. void MF_AbreMiVentana(void)
  533. {
  534.         
  535.     /* 
  536.     En vez de usar la función NewWindow(), empleamos la función
  537.     GetNewWindow() que crea una ventana leyendo el formato de la misma
  538.     contenido en un recurso WIND, dentro de los recursos de la aplicación.
  539.     
  540.     GetNewWindow requiere los siguientes parámetros:
  541.     
  542.     GetNewWindow(short windowID, void *wStorage, WindowRef behind)
  543.     Por el momento, el único al que nos referiremos es:
  544.     windowID:     El número de recurso del tipo WIND definiendo la ventana.
  545.     
  546.     */
  547.     gMiVentana = GetNewWindow(kMiVentanaRsrcID, nil, (WindowPtr)-1L);
  548.   
  549.   if(gMiVentana == nil) 
  550.           ExitToShell();    /* Si la creación de la ventana falla, 
  551.                                               posiblemente sea debido a falta de memoria libre
  552.                                               Lo más aconsejable es salir de la aplicación */
  553.       
  554. } /* fin de MF_AbreMiVentana() */
  555.  
  556.  
  557.  
  558. /****************************************************************/
  559. /* MF_EscribeTexto                                                                                         */ 
  560. /****************************************************************/
  561. /*
  562.     Dibuja en nuestra ventana un texto.
  563.         
  564.     Recibe:     nada
  565.     Cambia:      Dibuja en la ventana un texto.
  566.     Salida:   nada
  567. */
  568. void MF_EscribeTexto(void)
  569. {
  570.              MoveTo(30,30);
  571.              DrawString("\pMacFormat - C de Cerca nº 4");
  572.  
  573. }